package org.groupg.practice;

import com.opencsv.CSVParserBuilder;
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import com.opencsv.CSVWriter;
import com.opencsv.exceptions.CsvException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.Reader;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.List;

/**
 * 高级CSV处理工具
 */
public class AdvancedCsvProcessor {
    private static final Logger logger = LoggerFactory.getLogger(AdvancedCsvProcessor.class);

    /**
     * 自定义格式写入CSV
     * @param filePath 文件路径
     * @param separator 字段分隔符
     * @param quoteChar 引号字符
     * @param escapeChar 转义字符
     * @param lineEnd 行结束符
     */
    public static void writeWithCustomFormat(String filePath, char separator,
                                            char quoteChar, char escapeChar,
                                            String lineEnd) {
        try (CSVWriter writer = new CSVWriter(new FileWriter(filePath),
                separator, quoteChar, escapeChar, lineEnd)) {

            logger.info("开始写入自定义格式CSV: {}", filePath);

            // 写入注释行
            writer.writeNext(new String[]{"# 自定义格式CSV示例"}, false);
            writer.writeNext(new String[]{"# 分隔符: " + separator + ", 引号: " + quoteChar}, false);

            // 写入标题
            writer.writeNext(new String[]{"ID", "Product", "Price", "Description"});

            // 写入数据行（包含特殊字符）
            writer.writeNext(new String[]{"P-1001", "Laptop", "1200.99", "高性能笔记本"});
            writer.writeNext(new String[]{"P-1002", "Wireless \"Bluetooth\" Headphones", "99.50", "无线耳机"});
            writer.writeNext(new String[]{"P-1003", "4K|Monitor", "450.00", "4K显示器|支持HDR"});
            writer.writeNext(new String[]{"P-1004", "Mechanical Keyboard\n(Cherry MX)", "75.25", "机械键盘\n青轴"});

            logger.info("成功写入自定义格式CSV文件: {}", filePath);
        } catch (Exception e) {
            logger.error("写入自定义格式CSV失败", e);
        }
    }

    /**
     * 追加数据到CSV文件
     * @param filePath 文件路径
     * @param records 要追加的记录
     * @param separator 字段分隔符
     */
    public static void appendToCsv(String filePath, List<String[]> records, char separator) {
        try {
            Path path = Paths.get(filePath);

            // 如果文件不存在，创建并写入标题
            if (!Files.exists(path)) {
                logger.info("文件不存在，创建新文件: {}", filePath);
                try (Writer writer = Files.newBufferedWriter(path)) {
                    CSVWriter csvWriter = new CSVWriter(writer, separator,
                            CSVWriter.NO_QUOTE_CHARACTER,
                            CSVWriter.DEFAULT_ESCAPE_CHARACTER,
                            CSVWriter.DEFAULT_LINE_END);
                    csvWriter.writeNext(new String[]{"ID", "Product", "Price", "Description"});
                }
            }

            // 追加模式写入
            try (Writer writer = Files.newBufferedWriter(path, StandardOpenOption.APPEND);
                 CSVWriter csvWriter = new CSVWriter(writer, separator,
                         CSVWriter.NO_QUOTE_CHARACTER,
                         CSVWriter.DEFAULT_ESCAPE_CHARACTER,
                         CSVWriter.DEFAULT_LINE_END)) {

                logger.info("开始追加数据到文件: {}", filePath);

                for (String[] record : records) {
                    csvWriter.writeNext(record);
                    logger.debug("追加记录: {}", Arrays.toString(record));
                }

                logger.info("成功追加 {} 条记录到文件", records.size());
            }
        } catch (Exception e) {
            logger.error("追加数据到CSV失败", e);
        }
    }

    /**
     * 流式处理大型CSV文件
     * @param filePath 文件路径
     * @param separator 字段分隔符
     * @param batchSize 批处理大小
     */
    public static void processLargeCsv(String filePath, char separator, int batchSize) {
        logger.info("开始处理大型CSV文件: {}", filePath);
        int totalCount = 0;
        int batchCount = 0;

        try (Reader reader = new FileReader(filePath);
             CSVReader csvReader = new CSVReaderBuilder(reader)
                 .withSkipLines(2) // 跳过注释行
                 .withCSVParser(new CSVParserBuilder()
                     .withSeparator(separator)
                     .build())
                 .build()) {

            String[] nextRecord;
            while ((nextRecord = csvReader.readNext()) != null) {
                // 处理单条记录
                processRecord(nextRecord);
                totalCount++;
                batchCount++;

                // 批处理统计
                if (batchCount >= batchSize) {
                    logger.info("已处理 {} 条记录, 总计: {}", batchSize, totalCount);
                    batchCount = 0;
                }
            }

            logger.info("文件处理完成! 总计处理 {} 条记录", totalCount);
        } catch (Exception e) {
            logger.error("处理大型CSV文件失败", e);
        }
    }

    private static void processRecord(String[] record) {
        // 实际业务处理逻辑
        // 这里简单记录调试信息
        if (logger.isDebugEnabled()) {
            logger.debug("处理记录: {}", Arrays.toString(record));
        }

        // 示例：验证数据格式
        if (record.length < 4) {
            logger.warn("无效记录: 字段数量不足 - {}", Arrays.toString(record));
        }
    }
}
